package nb.diskfilesystem.model;

import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import nb.diskfilesystem.ui.MainView;

import java.io.Serializable;
import java.util.Arrays;

// 文件分配表（FAT）
public class FAT implements Serializable {
    public static final int END_OF_FILE = -1;  // 文件结束标志
    public static final int Bad_Block = 254;  // 坏块
    private int[] fat;  // 文件分配表

    public static final int totalBlocks = 128; // 磁盘总块数

    private BorderPane borderPane;


    // 初始化文件分配表
    public void FileAllocationTable(int totalBlocks) {
        fat = new int[totalBlocks];
        Arrays.fill(fat, 0); // 初始化fat数组
        fat[0] = END_OF_FILE;  // 第1个块
        fat[1] = END_OF_FILE;  // 第2个块
    }

    // 在borderPane显示文件分配表
    public void start() {
        System.out.println("文件分配表 (FAT) 显示");
        borderPane = (BorderPane) MainView.rootNode.lookup("#FAT_table");

        // 检查是否成功找到 borderPane
        if (borderPane == null) {
            System.err.println("未能找到 ID 为 FAT_table 的 BorderPane");
            return;
        }

        int totalBlocks = 128;
        FileAllocationTable(totalBlocks); // 初始化FAT

        TableView<BlockEntry> tableView = new TableView<>(); // 创建表格

        // 创建表格1列
        TableColumn<BlockEntry, Integer> blockColumn = new TableColumn<>("块号");
        blockColumn.setCellValueFactory(new PropertyValueFactory<>("blockNumber"));
        blockColumn.setPrefWidth(86); // 设置宽度

        // 创建表格2列
        TableColumn<BlockEntry, Integer> statusColumn = new TableColumn<>("状态");
        statusColumn.setCellValueFactory(new PropertyValueFactory<>("status"));
        statusColumn.setPrefWidth(86); // 设置宽度

        // 创建表格3列
        TableColumn<BlockEntry, Integer> content = new TableColumn<>("文件/文件夹");
        content.setCellValueFactory(new PropertyValueFactory<>("content"));
        content.setPrefWidth(86); // 设置宽度


        tableView.getColumns().add(blockColumn);
        tableView.getColumns().add(statusColumn);
        tableView.getColumns().add(content);

        // 填充表格数据
        for (int i = 0; i < fat.length; i++) {
            tableView.getItems().add(new BlockEntry(i + 1, fat[i],' '));
        }

        borderPane.setCenter(tableView);
        System.out.println("文件分配表 (FAT) 显示完成!");
    }

    public static class BlockEntry {
        private final int blockNumber;// 块号
        private final int status;// 状态
        private final char content;// 文件/文件夹名字

        public BlockEntry(int blockNumber, int status,char content) {
            this.blockNumber = blockNumber;
            this.status = status;
            this.content = content;
        }

        public int getBlockNumber() {
            return blockNumber;
        }

        public int getStatus() {
            return status;
        }

        public char getContent() {
            return content;
        }
    }

    // 标记块
    public void markBlock(int block) {
        if (isValidBlock(block)) {
            fat[block] = END_OF_FILE;
        }
    }

    public void markBadBlock(int block) {
        if (isValidBlock(block)) {
            fat[block] = Bad_Block;
        }
    }

    // 分配块
    public int allocateBlock() {
        for (int i = 2; i < fat.length; i++) {  // 从第2个块开始分配
            if (fat[i] == 0) {
                fat[i] = END_OF_FILE;  // 新分配的块默认结束
                return i;
            }
        }
        return -1;  // 无可用块
    }

    // 释放块
    public void freeBlock(int block) {
        if (isValidBlock(block)) {
            fat[block] = 0;
        }
    }

    // 设置当前块的下一个块
    public void setNextBlock(int currentBlock, int nextBlock) {
        if (isValidBlock(currentBlock) && isValidBlock(nextBlock)) {
            fat[currentBlock] = nextBlock;
        }
    }

    // 获取当前块的下一个块
    public int getNextBlock(int block) {
        if (isValidBlock(block)) {
            return fat[block];
        }
        return -1;  // 无效块
    }

    // 显示文件分配表
    public void displayFAT() {
        FileAllocationTable(totalBlocks);
        System.out.println("文件分配表内容为（FAT）：");
        for (int i : fat) {
            System.out.printf("%3d", i);
        }
        System.out.println();
    }

    // 判断块是否有效
    private boolean isValidBlock(int block) {
        return block >= 0 && block < fat.length;
    }

}
